package lapsnake.model.dnd;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JPanel;

import owg.util.awt.VerticalLayout;
import lapsnake.model.LapNode;
import lapsnake.model.data.ChildField;

public class FieldPanel extends JPanel
{
	private static final long serialVersionUID = 9211266683183789825L;
	
	protected ArrayList<NodePanel<?>> nodePanels = new ArrayList<>();
	
	private StmtPanel rootPanel;
	private ChildField<? extends LapNode> body;
	private NodePanel<?> owner;	
	
	public FieldPanel(NodePanel<?> owner, ChildField<? extends LapNode> field)
	{
		this.body = field;
		this.owner = owner;
		this.rootPanel = owner.getRootPanel();
		setLayout(new VerticalLayout(-ActionNodePanel.MINOR_ICON_DIM, VerticalLayout.LEFT, VerticalLayout.TOP));
		setBorder(BorderFactory.createEmptyBorder());
		setOpaque(false);
		for(LapNode n : field)
		{
			NodePanel<?> p = n.getCompactUI(rootPanel);
			nodePanels.add(p);
			add(p);
		}
		if(field.isEmpty())
		{
			Dimension dim = new Dimension(ActionNodePanel.MINOR_ICON_DIM,1);
			add(new Box.Filler(dim, dim, dim));
		}
		owner.registerFieldPanel(this);
	}
	public Class<? extends LapNode> getFieldType()
	{
		return body.getType();
	}
	
	public Point getAbsoluteLocation()
	{
		Point loc = getLocationOnScreen();
		Point root = rootPanel.getLocationOnScreen();
		loc.translate(-root.x, -root.y);
		return loc;
	}
	
	/**Gets the socket at the indicated point in the absolute drag and drop space, null if none.*/
	public Socket getSocketAt(Point p)
	{
		Point myLoc = getAbsoluteLocation();
		int y = myLoc.y;
		if(p.x < myLoc.x -ActionNodePanel.MINOR_ICON_DIM)
			return null;
		if(nodePanels.isEmpty() && new Rectangle(myLoc.x-4, myLoc.y, getWidth()+ActionNodePanel.MINOR_ICON_DIM+10, owner.getHeight()).contains(p))
			return new Socket(rootPanel, this, body, 0, false, new Point(0, 0));
		
		for(int i = 0; i<nodePanels.size(); i++)
		{
			NodePanel<? extends LapNode> nui = nodePanels.get(i);
			int ny = y+nui.getHeight()-ActionNodePanel.MINOR_ICON_DIM;
			if( (p.y >= y || (i == 0 && p.y >= myLoc.y-ActionNodePanel.MINOR_ICON_DIM)) && 
				(p.y < ny || (i == nodePanels.size()-1 && p.y < ny + ActionNodePanel.MINOR_ICON_DIM)))
			{
				if (p.x > myLoc.x + nui.getWidth())
					continue;
				if (p.x > myLoc.x+ActionNodePanel.MAJOR_ICON_DIM || (p.y >= ny && p.x > myLoc.x))
				{
					Socket s = nui.getSocketAt(p);
					if(s != null)
						return s;
				}
				else 
					return new Socket(rootPanel, nui, body, i, false, new Point(0, 0));
			}
			y = ny;
		}
		return null;
	}
	
	@Override
	public String toString()
	{
		return "FP: "+body;
	}
}
